#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <EEPROM.h> 

#include "config.h"

#define EEPROM_WIFI_Name_Addr   10     //WIFI名字的地址
#define EEPROM_WIFI_Key_Addr    40     //WIFI密码的地址
#define EEPROM_Name_Size_Addr   0     //WIFI名字的长度地址
#define EEPROM_Key_Size_Addr    1     //WIFI密码的长度地址

String WIFI_Name  = "牛嘿嘿";      //WIFI名字
String WIFI_Key   = "asdzxc123";     //密码


static uint8_t LED_P = 5;
static uint8_t pwm =0;
static uint8_t last_pwm = 0;

//length写入记录字符串长度的地址，addr是字符串的地址，str为要保存的字符串
static void Write_String(int len_addr,int addr,String str){
//  EEPROM.write(len_addr, str.length());//写入str字符串的长度
  EEPROM.write(len_addr, str.length()-1);//写入str字符串的长度
  //把str所有数据逐个保存在EEPROM
  for (int i = 0; i < str.length(); i++){
    EEPROM.write(addr + i, str[i]);
  }
  EEPROM.commit();
}

//length位是字符串长度，addr是起始位(字符串首地址)
static String Read_String(int len_addr, int addr){ 
  String data = "";
  char length = EEPROM.read(len_addr);    //读取记录在EEPROM中的数据长度
  //从EEPROM中逐个取出每一位的值，并链接
  for (int i = 0; i < length; i++){
    data += char(EEPROM.read(addr + i));
  }
  return data;
}

static void replyToServer(void* arg) {
	AsyncClient* client = reinterpret_cast<AsyncClient*>(arg);

	// send reply
	if (client->space() > 32 && client->canSend()) {
		char message[32];
		client->add(message, strlen(message));
		client->send();
	}
}

/* event callbacks */
static void handleData(void* arg, AsyncClient* client, void *data, size_t len) {
	Serial.printf("\n data received from %s \n", client->remoteIP().toString().c_str());
	Serial.write((uint8_t*)data, len);
  if(len>0)
  {
    uint8_t* da = (uint8_t*)data;
    //地址码
    if(da[0]==0x00)
    {
       //功能码
       if(da[1] == 0x01)
       {
         if(da[2]>255){
          da[2] = 255;
         } 
         pwm = da[2];
         analogWrite(LED_P, pwm);
         Serial.printf("\n PWM set to %d",da[2] );
       }
       if(da[1] == 0x02)
       {
        for (size_t i = 0; i < 255; i++)
        {
          /* code */
          analogWrite(LED_P, i);
          delay(2);
        }
        
       }
       
    } 
  }
}



void onConnect(void* arg, AsyncClient* client) {
	Serial.printf("\n client has been connected to %s on port %d \n", SERVER_HOST_NAME, TCP_PORT);
	replyToServer(client);
}

void onClient(void* arg, AsyncClient* client) {
    Serial.printf("\n client connected ! %s",client->remoteIP().toString().c_str());
    client->onData(&handleData, client);
}





void setup() {

    pinMode(LED_P,OUTPUT);
    for (size_t i = 0; i < 255; i++)
        {
          /* code */
          analogWrite(LED_P, i);
          delay(2);
        }
    Serial.begin(9600);
    // Write_String(EEPROM_Name_Size_Addr, EEPROM_WIFI_Name_Addr,WIFI_Name);
    // Write_String(EEPROM_Key_Size_Addr, EEPROM_WIFI_Key_Addr,WIFI_Key);
    // if(EEPROM.read(EEPROM_Name_Size_Addr)!=0xff)            //如果WIFI名称长度有改变，则读取名称
    // {
    //   WIFI_Name  = Read_String(EEPROM_Name_Size_Addr, EEPROM_WIFI_Name_Addr);    //读取WIFI名称，
    //   Serial.printf("\n wifi name %s",WIFI_Name.c_str());
    // }
    // if(EEPROM.read(EEPROM_Key_Size_Addr)!=0xff)            //如果WIFI密码长度有改变，则读取密码
    // {
    //   WIFI_Key  = Read_String(EEPROM_Key_Size_Addr, EEPROM_WIFI_Key_Addr);    //读取WIFI密码，
    //   Serial.printf("\n wifi key %s",WIFI_Key.c_str());
    // }
    // 连接到Wi-Fi
    WiFi.begin(WIFI_Name, WIFI_Key);
    //如果没有连接上串口就一直输出 ...
    //如果连接不上请确保你要连接的WIFI不是5G频段!
    //大部分ESP32系列都只能连接2.4G频段!
    int connectTime = 0;
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
        connectTime+=1;
        if(connectTime>10)
        {
          Serial.printf("\n wifi连接失败。");
          return;
        }
    }
    Serial.printf("\n wifi connected! %s",WiFi.BSSIDstr().c_str());
	  delay(20);
    AsyncServer* server = new AsyncServer(10086);
    server->onClient(&onClient,server);
    server->begin();
}

void loop() {
  //  if(last_pwm!=pwm)
  //  {
  //   last_pwm = pwm;
  //   analogWrite(LED_P, pwm);
  //  }
   
  //  //接收信号
  //  //如果串口2的缓冲区有数据
  //   if (Serial.available()) 
  //   {
  //     //定义数据储存数组
  //     byte da[100];
  //     //读取串口2
  //     Serial.readBytes(da, 100);

  //     if(da[1]==0x02)
  //      {
  //       //设置wifi 名称密码
  //       int namelen = da[2];
  //       int keylen = da[3];
  //       String namestr = String();
  //       for (int i = 0; i < namelen; i++)
  //       {
  //         namestr.concat(da[4+i]);
  //       }
  //       Write_String(EEPROM_Name_Size_Addr,EEPROM_WIFI_Name_Addr,namestr);
  //       String keystr = String();
  //       for (int i = 0; i < keylen; i++)
  //       {
  //         keystr.concat(da[4+namelen+i]);
  //       }
  //       Write_String(EEPROM_Key_Size_Addr,EEPROM_WIFI_Key_Addr,keystr);
  //       Serial.printf("\n wifiName %s wifiKey %s",namestr.c_str(),keystr.c_str());
  //      }
  //   }

}